home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / macros / latex209 / contrib / trees / pstrees / trees.c < prev    next >
C/C++ Source or Header  |  1994-01-28  |  7KB  |  373 lines

  1. # include "align.h"
  2. /* VAX VMS
  3. # include <unixio>
  4. */
  5. # include <stdio.h>
  6.  
  7. /* #define INC_COLUMNS */
  8.  
  9.   /* externals from slurp */
  10. extern char nextchar();
  11. extern char peekchar();
  12. extern int fetchline();
  13. extern void writeline();
  14. extern void skip_to();
  15. extern FILE *outstream;
  16.  
  17.  
  18. /* externals from words */
  19. extern void readword();
  20. extern void initstore();
  21.  
  22. /* types */
  23. struct tnode {
  24.   word name;
  25.   int branch, term, tri;
  26.   struct tnode *mother, *daughters, *next;
  27.   char tag[10];       /* text of tag held in charstore */
  28. };
  29.  
  30. typedef struct tnode treenode;
  31.  
  32. /* error stuff */
  33. int sinned   = FALSE;  /* error has occurred in run */
  34. int error = FALSE;  /* error has occurred in current example */
  35.  
  36. FILE  *error_file;
  37. char error_name[50];
  38.  
  39.  
  40. void goof(s)
  41. char *s;
  42. {
  43.   if (!sinned) {
  44.     error_file = fopen(error_name,"w");
  45.     sinned = TRUE;
  46.   }    
  47.   fprintf(stderr,"%s at line %d\n",s,linecount());
  48.   fprintf(error_file,"%s at line %d\n",s,linecount);
  49.   error = TRUE;
  50. }
  51.  
  52.   
  53.  
  54. char delmark = '|';  /* delimiter */
  55. int tagcount;        /* keeps track of tags */
  56.  
  57. /* strequ */
  58. int strequ(s1,s2)
  59. char *s1, *s2;
  60. {
  61.   if (strcmp(s1,s2) == 0)
  62.     return(TRUE);
  63.   else
  64.     return(FALSE);
  65. }
  66.  
  67. /* local node label & annotation-ending function */
  68. static int endlabel(c)
  69. char c;
  70. {
  71.  if (eoln() || c == delmark) {
  72.    return(TRUE);
  73.  }
  74.  else
  75.    return(FALSE);
  76. }
  77.  
  78. /* local command-word ending function */
  79. static int endcom(c)
  80. char c;
  81. {
  82.   if (c == ' ' || c == delmark) {
  83.     return(TRUE);
  84.   }
  85.   else
  86.     return(FALSE);
  87. }
  88.  
  89. /* adapted from K&R itoa */
  90. void convert(n,s)
  91. int n;
  92. char s[];
  93. {
  94.   int i;
  95.  
  96.   i = 0;
  97.   do {
  98.     s[i++] = n % 26 + 'a';
  99.   } while ((n /= 26) > 0);
  100.   s[i] = '\0';
  101. }
  102.  
  103. char grabchar()
  104. {
  105. char c;
  106.   c = nextchar();
  107.   if (c == '%') {
  108.     fetchline();
  109.     return(grabchar());
  110.   } else
  111.   return (c);
  112. }
  113.  
  114. /* allocates nodespace, reads in info, etc. */
  115. treenode *build_node()
  116. {
  117.   int go;
  118.  
  119.   treenode *node;
  120.   word holder;
  121.   char **pointer;
  122.  
  123.   pointer = &(holder.loc);
  124.   node = (treenode *)malloc(sizeof(treenode));
  125.   readword(&node->name,&go,endlabel,grabchar,FALSE);
  126.   node->next = NULL;
  127.   node->daughters = NULL;
  128.   node->mother = NULL;
  129.   node->tri = FALSE;
  130.   node->term = TRUE;
  131.   node->tag[0]='\0';
  132.   while (go) {
  133.     readword(&holder,&go,endcom,nextchar,FALSE);
  134.     if (strequ(*pointer,"tri"))
  135.       node->tri=TRUE;
  136.     else
  137.     if (strequ(*pointer,"tag")) {
  138.       readword(&holder,&go,endcom,nextchar,FALSE);
  139.       strcpy(node->tag,*pointer);
  140.     }
  141.   }
  142.  
  143.   if (node->tag[0] == '\0') {
  144.     node->tag[0] = 'Z';
  145.     convert(tagcount++,&(node->tag[1]));
  146.   }
  147.   return(node);
  148. }
  149.  
  150. /* gets a node, assuming that the line the node is on is already read
  151.    in */
  152. treenode *get_node()
  153. {
  154.   int pos,dpos;
  155.  
  156.   treenode *node;
  157.  
  158.   advanceeoln_pos(&pos);
  159.   if (eoln()) {
  160.     goof("blank line in tree");
  161.     fetchline();
  162.     return(NULL);
  163.   }
  164.   node = build_node();
  165.   fetchline();
  166.   advanceeoln_pos(&dpos);
  167.   if (dpos > pos) {
  168.     get_daughters(node,dpos);
  169.   }
  170.   return(node);
  171. }
  172.  
  173. get_daughters(node,dpos)
  174. treenode *node;   /* node of which daughters are being read */
  175. int dpos;         /* position where daughters are supposed to be */
  176. {
  177.   int pos;
  178.   treenode *current;
  179.  
  180.   current = get_node();
  181.   current->mother = node;
  182.   node->daughters = current;
  183.   node->term = FALSE;
  184.  
  185.   while (currentpos() == dpos && !error) { /* as long as we're getting daughters */
  186.     current->next = get_node();
  187.     current = current->next;
  188.     current->mother = node;
  189.   }
  190. }
  191.  
  192. void show_tree(node, ind)
  193. treenode *node;
  194. int ind;
  195. {
  196.   int i;
  197.  
  198.   if (node != NULL) {
  199.     for (i = 1; i<=ind; i++)
  200.       putc(' ', outstream);
  201.     fprintf(outstream,"%s\n",node->name.loc);
  202. if (node->tri) printf("TRI\n");
  203. printf("tag = %s\n",node->tag);
  204.     for (node = node->daughters; node !=NULL; node=node->next)
  205.       show_tree(node,ind+2);
  206.   }
  207. }
  208.  
  209.  
  210.  
  211. void write_tree(node, ind)
  212. treenode *node;
  213. int ind;
  214. {
  215.   int i;
  216.   treenode *mother;
  217.  
  218.   if (node != NULL) {
  219.     mother = node;
  220.     for (i = 1; i<=ind; i++)    /* print indentation */
  221.       putc(' ', outstream);
  222.     if (node->term) {
  223.       fprintf(outstream,"{\\tnode{%s}{%s}}",node->tag,node->name.loc);
  224.     }
  225.     else {
  226.       fprintf(outstream,"{\\ntnode{%s}{%s},\n",node->tag,node->name.loc);
  227.       for (node = node->daughters; node !=NULL; node=node->next)
  228.     write_tree(node,ind+2);
  229. /*
  230.       for (i = 1; i<=ind; i++)
  231.     putc(' ', outstream);
  232. */
  233.       putc('}',outstream);
  234.     };
  235.     
  236.     if (mother->next != NULL) fprintf(outstream,",\n");
  237. /*
  238.     else fprintf(outstream,"%\n");
  239.   if (node->next != NULL && node->mother != NULL)
  240.     putc(',',outstream);
  241.   putc('\n',outstream);
  242. */
  243.   }
  244. }
  245.  
  246. void draw_lines(node)
  247. treenode *node;
  248. {
  249.   int i;
  250.   char *m;   /* mother & daughter tags */
  251.   treenode *mother; /* mother */
  252.  
  253.   if (node != NULL) {
  254.     mother = node;
  255.     m = mother->tag;
  256.     for (node = mother->daughters; node !=NULL; node=node->next) {
  257.       if (node->tri)
  258.     fprintf(outstream,"\\nodetriangle{%s}{%s}%%\n",m,node->tag);
  259.       else
  260.     fprintf(outstream,"\\nodeconnect{%s}{%s}%%\n",m,node->tag);
  261.     }
  262.     for (node = mother->daughters; node !=NULL; node=node->next)
  263.       draw_lines(node);
  264.   }
  265. }
  266.  
  267.  
  268. void free_tree(node)
  269. treenode *node;
  270. {
  271.  
  272.     if (node !=NULL) {
  273.       for (node = node->daughters; node !=NULL; node=node->next)
  274.     free_tree(node);
  275.       free(node);
  276.       node=NULL;
  277.   }
  278. }
  279.  
  280.  
  281. void tree()
  282. {
  283.   treenode *node;
  284.  
  285.   delmark = '|';
  286.   error = FALSE;
  287.   tagcount = 0;
  288.  
  289.   init_store();
  290.   fetchline();
  291.   node=get_node();
  292.   if (!matchstr(".]") && !error)
  293.     goof("bad tree indentation");
  294.   if (error) {
  295.     fprintf(outstream,"\nBAD TREE\n");
  296.     error = FALSE;
  297.   }
  298.   else {
  299.     fprintf(outstream,"\\tree");
  300.     write_tree(node,0);
  301.     fprintf(outstream,"%%\n"),
  302.     draw_lines(node);
  303.   }
  304.   free_tree(node);
  305. }
  306.  
  307. void extendfilename(name,extension,result)
  308. /* chris: fix parameter declarations */
  309. char name[];
  310. char extension[];
  311. char result[];
  312. {
  313.   strcpy(result,name);
  314.   strcat(result,extension);
  315. }
  316.  
  317.  
  318.  
  319. main(argc, argv)
  320. int argc;
  321. char *argv[];
  322.  
  323. {
  324.  
  325.   char infile[200];
  326.   char outfile[200];
  327.  
  328.   char c;
  329.  
  330.   /* chris - let it run as filter */
  331.   if (argc < 2)
  332.     {
  333.       strcpy(infile, "stdin");
  334.       strcpy(error_name, "trees.err");
  335.     }
  336.   else
  337.     {
  338.       extendfilename(argv[1],".txp",infile);
  339.       extendfilename(argv[1],"_tx2.tex",outfile);
  340.       extendfilename(argv[1],".err",error_name);
  341.     }
  342.  
  343. /* VAX/VMS reading from logical `source', writing to logical `product'
  344.   open_source("source");
  345.   outstream = fopen("product","w");
  346. */
  347.  
  348.   if (open_source(infile)) {
  349.     /* chris - letting it run as a filter still */
  350.     if (argc < 2)
  351.       outstream = stdout;
  352.     else
  353.       outstream = fopen(outfile,"w"); 
  354.     while (fetchline()) {            /* as long as there's input */
  355.       if (nextchar() == '.') {     
  356.         if ((c = nextchar()) == '[') {   
  357.       tree();
  358.         }
  359. #ifdef INC_COLUMNS
  360.         else
  361.         if (c == '<') {
  362.           columns();
  363.         }
  364. #endif
  365.       }
  366.       else {
  367.         writeline();
  368.       }
  369.     }
  370.   } else printf("file `%s' not found\n",infile);
  371.   return(sinned);
  372. }
  373.